﻿#define TEST
#define DEBUG

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Collections;
using System.Runtime.InteropServices;

using SuperMapLib;

namespace JR_RouteAlarm
{
    public partial class Form1 : Form
    {
        private Utility utl = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                textBox1.Text = openFileDialog1.FileName;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                textBox2.Text = saveFileDialog1.FileName;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            button3.Enabled = false;
            button4.Enabled = true;

            try
            {
                Initialize();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);

                button3.Enabled = true;
                button4.Enabled = false;
                
                return;
            }

#if DEBUG
            try
            {
#endif
                MakeBuffer();
#if DEBUG
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);

                utl.Dispose();

                button3.Enabled = true;
                button4.Enabled = false;

                return;
            }
#endif
#if UNTEST
            if (utl.objSource.Datasets != null && utl.objSource.Datasets.Count > 0)
            {
                Examples example = new Examples(utl.objSource.Datasets);
            }
#endif
            CrossArea crsA = new CrossArea(axSuperMap1, utl);
            crsA.BuildLayerForMap();

            utl.Dispose();

            button3.Enabled = true;
            button4.Enabled = false;
        }

        private void Initialize()
        {
            Utility.datasourceAlias = "areamap"; //textBox1.Text.Substring(textBox1.Text.IndexOf(".sdb"));
            utl = new Utility(axSuperWorkspace1, textBox1.Text);
        }

        private void MakeBuffer()
        {
            soDatasets objDSs = null;

            objDSs = utl.objSource.Datasets;
            if (objDSs != null && objDSs.Count > 0)
            {
                soDataset objDS = null;
                soDatasetVector objDatasetV = null;
                soStrings objStrFields = null;

                objStrFields = new soStrings();
                objStrFields.Add(Route.FLD_FEATURE_CD);
                objStrFields.Add(Route.FLD_DAIBUN_CD);
                objStrFields.Add(Route.FLD_TSUUSHO_CD);

                objDS = objDSs[Utility.ROUTE_DATASET_NAME];
                if (!objDS.Name.Contains(Utility.BUFFER_TITLE))
                {
#if DEBUG
                    try
                    {
#endif
                        objDatasetV = objDS as soDatasetVector;
                        MakeRoutes(objDatasetV, objStrFields);
#if DEBUG
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);

                        Marshal.ReleaseComObject(objStrFields);
                        objStrFields = null;
                        Marshal.ReleaseComObject(objDS);
                        objDS = null;
                        //Marshal.ReleaseComObject(objDSs);
                        //objDSs = null;

                        return;
                    }

                    try
                    {
#endif
                        BuildBuffer(Utility.BUFFER_TITLE + objDS.Name, objDatasetV.GetFieldInfos());
#if DEBUG
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);

                        Marshal.ReleaseComObject(objStrFields);
                        objStrFields = null;
                        Marshal.ReleaseComObject(objDS);
                        objDS = null;
                        //Marshal.ReleaseComObject(objDSs);
                        //objDSs = null;

                        return;
                    }
#endif
                }

                Marshal.ReleaseComObject(objStrFields);
                objStrFields = null;
                Marshal.ReleaseComObject(objDS);
                objDS = null;
                //Marshal.ReleaseComObject(objDSs);
                //objDSs = null;
            }
        }

        private void MakeRoutes(soDatasetVector objDSV, soStrings objStrFields)
        {
            soRecordset objRS = null;

            objDSV.ClearRecordsets();
            objRS = objDSV.Query(
                Route.FLD_FEATURE_CD + " = '0102' and " +
                Route.FLD_DAIBUN_CD + " = '01' and " +
                Route.FLD_TSUUSHO_CD + " = '476'", false, objStrFields, 
                "group by " + Route.FLD_FEATURE_CD + ", " + Route.FLD_DAIBUN_CD + ", " + Route.FLD_TSUUSHO_CD);

            if (objRS != null && objRS.RecordCount > 0)
            {
                if (!objRS.IsBOF())
                {
                    objRS.MoveFirst();
                }

                IRoute route = new Route(utl.objSource.Datasets);
#if DEBUG
                for (int j = 0; j < objRS.RecordCount; objRS.MoveNext(), j++)
#else
                for (; !objRS.IsEOF(); objRS.MoveNext())
#endif
                {
                    try
                    {
                        route.MakeBufferForRoute(objDSV, objRS);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);

                        objRS.Close();
                        Marshal.ReleaseComObject(objRS);
                        objRS = null;

                        return;
                    }
                }
                objRS.Close();
                objDSV.Close();

                Marshal.ReleaseComObject(objRS);
                objRS = null;
            }
        }

        private void BuildBuffer(string dsName, soFieldInfos objFields)
        {
            soDataset objDS = null;

            if (!utl.objSource.IsAvailableDatasetName(dsName))
            {
                if (!utl.objSource.DeleteDataset(dsName))
                {
                    throw new Exception("Dataset delete failed!");
                }
            }

            objDS = utl.objSource.CreateDataset(
                dsName, seDatasetType.scdRegion, seDatasetOption.scoDefault, null);
            if (objDS!= null)
            {
                soDatasetVector objDatasetV = null;
                soRecordset objRecords = null;

                objDatasetV = objDS as soDatasetVector;
                objDatasetV.CreateField(objFields[Route.FLD_FEATURE_CD]);
                objDatasetV.CreateField(objFields[Route.FLD_DAIBUN_CD]);
                objDatasetV.CreateField(objFields[Route.FLD_TSUUSHO_CD]);
                soFieldInfo objField = new soFieldInfo();
                objField.Caption = Route.FLD_LABELTEXT;
                objField.Name = Route.FLD_LABELTEXT;
                objField.Type = seFieldType.scfText;
                objDatasetV.CreateField(objField);
                //objDatasetV.Flush();
                objRecords = objDatasetV.Query("-1 < 0", true, null, "");
                if (objRecords != null)
                {
#if DEBUG
                    int i = 0, j = 0;
#endif
                    soGeometry objMetry = null;
                    string[] strRoute = null;
                    //foreach (object val in Utility.routeLnWithBfr.Values)
                    foreach (object key in Utility.routeLnWithBfr.Keys)
                    {
                        //objMetry = val as soGeometry;
                        objMetry = Utility.routeLnWithBfr[key] as soGeometry;
                        strRoute = new string[] { "0000", "00", "000", "" };
                        if (!key.GetType().Equals(typeof(soGeoLineClass)))
                        {
                            object[] obj = key as object[];
                            strRoute[0] = (obj[1] as string[])[0];
                            strRoute[1] = (obj[1] as string[])[1];
                            strRoute[2] = (obj[1] as string[])[2];
                            strRoute[3] = "ゾーン（23.9～25.5km）武蔵野線　大宮支線　西浦和支線";
                        }
#if DEBUG
                        if ((i = objRecords.AddNew(objMetry, false)) > 0)
                        {
                            Console.WriteLine("{0}, {1}", ++j, i);
#else
                        if (objRecords.AddNew(objMetry, false) > 0)
                        {
#endif
                            objRecords.SetFieldValue(Route.FLD_FEATURE_CD, strRoute[0]);
                            objRecords.SetFieldValue(Route.FLD_DAIBUN_CD, strRoute[1]);
                            objRecords.SetFieldValue(Route.FLD_TSUUSHO_CD, strRoute[2]);
                            objRecords.SetFieldValue("LabelText", strRoute[3]);

                            if (objRecords.Update() == -1)
                            {
                                objRecords.Close();
                                objDatasetV.Close();

                                Marshal.ReleaseComObject(objRecords);
                                objRecords = null;
                                Marshal.ReleaseComObject(objMetry);
                                objMetry = null;
                                Marshal.ReleaseComObject(objDatasetV);
                                objDatasetV = null;
                                Marshal.ReleaseComObject(objDS);
                                objDS = null;

                                throw new Exception("Build buffer failed!");
                            }
                        }
                        else
                        {
                            Console.WriteLine("{0}, {1}", ++j, i);

                            objRecords.Close();
                            objDatasetV.Close();

                            Marshal.ReleaseComObject(objRecords);
                            objRecords = null;
                            Marshal.ReleaseComObject(objMetry);
                            objMetry = null;
                            Marshal.ReleaseComObject(objDatasetV);
                            objDatasetV = null;
                            Marshal.ReleaseComObject(objDS);
                            objDS = null;

                            throw new Exception("Add new failed!");
                        }
                    }
                    objRecords.Close();
                    objDatasetV.Close();

                    //utl.objSource.Flush(dsName);

                    Marshal.ReleaseComObject(objRecords);
                    objRecords = null;
                    Marshal.ReleaseComObject(objMetry);
                    objMetry = null;
                    Marshal.ReleaseComObject(objDatasetV);
                    objDatasetV = null;
                }

                Marshal.ReleaseComObject(objDS);
                objDS = null;
            }
        }
    }
}